package com.lsht.common.word;

import cn.hutool.core.util.StrUtil;
import com.aspose.cells.*;
import com.aspose.cells.PageSetup;
import com.aspose.cells.PdfSaveOptions;
import com.aspose.words.*;
import com.aspose.words.BorderType;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.lsht.common.constant.PmConstants;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hslf.usermodel.*;
import org.apache.poi.xslf.usermodel.*;

import java.awt.*;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

/**
 * word处理
 */
@Slf4j
@SuppressWarnings("all")
public class AsposeWordUtil {

    // 公司购买的license
    private static final String LIC = "<License>\n" +
            "    <Data>\n" +
            "        <Products>\n" +
            "            <Product>Aspose.Total for Java</Product>\n" +
            "            <Product>Aspose.Words for Java</Product>\n" +
            "        </Products>\n" +
            "        <EditionType>Enterprise</EditionType>\n" +
            "        <SubscriptionExpiry>20991231</SubscriptionExpiry>\n" +
            "        <LicenseExpiry>20991231</LicenseExpiry>\n" +
            "        <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>\n" +
            "    </Data>\n" +
            "    <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>\n" +
            "</License>";

    private static boolean haveLoad = false;

    private static AsposeWordUtil wordStyleUtil = new AsposeWordUtil();

    public static AsposeWordUtil getInstance() {
        return wordStyleUtil;
    }

    /**
     * 获取文档
     *
     * @param template 导出word文档模板
     */
    public Document getDocument(String template) throws Exception {
        // 加载License
        registeLicense();
        Document doc = new Document();
        if (null != template) {
            try {
                doc = new Document(Files.newInputStream(Paths.get(template)));
            } catch (Exception e) {
                throw new Exception("没有找到导出模板!");
            }
        }
        return doc;
    }

    /**
     * 获取文档
     *
     * @param in 导出word文档模板
     * @return
     * @throws Exception
     */
    public Document getDocument(InputStream in) throws Exception {
        // 加载License
        registeLicense();

        Document doc = new Document();

        if (null != in) {
            try {
                doc = new Document(in);
            } catch (Exception e) {
                throw new Exception("没有找到文件!");
            }
        }
        return doc;
    }

    /**
     * 清除格式
     *
     * @param builder
     */
    private static void cleanFormatting(DocumentBuilder builder) throws Exception {
        // 清除字体格式
        builder.getFont().clearFormatting();
        builder.getParagraphFormat().clearFormatting();
    }

    /**
     * 文档保存
     *
     * @param expWordFile
     * @param doc
     * @throws Exception
     */
    private void saveDoc(File expWordFile, Document doc) throws Exception {
        doc.updateFields();
        doc.updatePageLayout();

        doc.save(expWordFile.getPath() + File.separatorChar + expWordFile.getName() + ".docx");
    }

    /**
     * 创建另外一个章节
     *
     * @param doc
     * @throws Exception
     */
    private void addSection(Document doc) throws Exception {
        Section section = new Section(doc);
        doc.getSections().add(section);
    }

    /**
     * 插入目录
     *
     * @param builder
     * @param doc
     * @throws Exception
     */
    private void insertTableOfContent(DocumentBuilder builder, Document doc) throws Exception {
        builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER);
        builder.getFont().setSize(32);
        // 设置加粗
        builder.getFont().setBold(true);
        builder.writeln("目    录");
        builder.getParagraphFormat().clearFormatting();

        builder.insertTableOfContents("\\o \"1-3\" \\h \\z \\u");
        addSection(doc);
    }

    /**
     * 插入页码
     *
     * @param builder
     */
    private void insertPageNum(DocumentBuilder builder) throws Exception {
        // 将builder移动至页脚
        builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY);
        // 设置起始页码
        builder.getPageSetup().setPageStartingNumber(1);
        builder.getParagraphFormat().getBorders().getByBorderType(BorderType.TOP).setLineStyle(LineStyle.SINGLE);
        // 页码对齐方式(居中,居左,居右)
        builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER);
        builder.write("第");
        // 插入页数
        builder.insertField("PAGE", "PAGE");
        builder.write("页    共");
        // 插入总共的页数
        builder.insertField("NUMPAGES", "NUMPAGES");
        builder.write("页");
    }

    /**
     * 加载license流避免导出word出现侵权提示
     */
    private void registeLicense() {
        if (!haveLoad) {
            InputStream licenseStream = new ByteArrayInputStream(LIC.getBytes());
            License license = new License();
            try {
                license.setLicense(licenseStream);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                haveLoad = false;
            }
            haveLoad = true;
        }
    }

    /**
     * @param in      word IO流
     * @param pdfPath pdf输出路径
     * @return 返回pdf IO流
     */
    public static InputStream doc2pdf(InputStream in, String pdfPath) {
        FileOutputStream os = null;
        FileInputStream inputStream = null;
        try {
            File file = new File(pdfPath); // 新建一个空白pdf文档
            os = new FileOutputStream(file);
            // in是将要被转化的word文档流
            Document doc;
            doc = AsposeWordUtil.getInstance().getDocument(in);
            doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML,
            // OpenDocument, PDF, EPUB, XPS, SWF
            // 相互转换
            os.close();

            if (!file.exists()) {
                return null;
            } else {
                inputStream = new FileInputStream(file);
                return inputStream;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            try {
                os.close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
        return inputStream;
    }

    /**
     * @param wordPath word路径
     * @param pdfPath  pdf输出路径
     * @return 返回 成功true 失败false
     */
    public static boolean doc2pdf(String wordPath, String pdfPath) {

        FileOutputStream os = null;
        FileInputStream inputStream = null;
        try {
            FileInputStream in = new FileInputStream(new File(wordPath));
            // os = new FileOutputStream(pdfPath);
            // 新建一个空白pdf文档
            File file = new File(pdfPath);
            os = new FileOutputStream(file);
            // in是将要被转化的word文档流
            Document doc;
            doc = AsposeWordUtil.getInstance().getDocument(in);
            // 全面支持DOC, DOCX, OOXML, RTF HTML,
            doc.save(os, SaveFormat.PDF);
            // OpenDocument, PDF, EPUB, XPS, SWF
            // 相互转换
            os.close();
            if (!file.exists()) {
                return false;
            } else {
                return true;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return false;
    }

    /**
     * @description: excel转pdf
     * @params: source:源文件地址,target:转换后文件路径,fileExt:后缀
     * @return:
     * @author:
     * @Date:
     */
    public static void excel2pdf(String source, String target, String fileExt) throws Exception {
        // 验证License 若不验证则转化出的pdf文档会有水印产生
        if (!haveLoad) {
            InputStream licenseStream = new ByteArrayInputStream(LIC.getBytes());
            License license = new License();
            try {
//                license.setLicense(licenseStream);
                com.aspose.cells.License aposeLic = new com.aspose.cells.License();
                //设置license 去除水印
                aposeLic.setLicense(licenseStream);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                haveLoad = false;
            }
            haveLoad = true;
        }
        // 获取所有工作表
        Workbook workbook = new Workbook(source);
        WorksheetCollection worksheets = workbook.getWorksheets();
        for (int i = 0; i < worksheets.getCount(); i++) {
            // 获取当前工作表
            Worksheet worksheet = worksheets.get(i);

            // 将工作表的打印设置设置为适应一页
            PageSetup pageSetup = worksheet.getPageSetup();
            pageSetup.setZoom(50);  // 设置缩放比例为100%
//            pageSetup.setFitToPagesWide(1);  // 设置自适应页面宽度
        }
        // 保存为 PDF 格式
        PdfSaveOptions options = new PdfSaveOptions();
        String replace = source.replace(fileExt, "pdf");
        workbook.save(replace, options);
        // 释放资源
        workbook.dispose();
//        try {
//            // 原始excel路径
//            Workbook wb = new Workbook(source);
//            // 将工作表的打印设置设置为适应一页
//            // 获取第一个工作表
//            Worksheet worksheet = wb.getWorksheets().get(0);
//            com.aspose.cells.PageSetup pageSetup = worksheet.getPageSetup();
//            pageSetup.setZoom(100);  // 设置缩放比例为100%
//            pageSetup.setFitToPagesWide(1);  // 设置自适应页面宽度
//            //验证路径
//            try {
//                if (!(new File(target).isDirectory())) {
//                    new File(target).mkdirs();
//                }
//            } catch (SecurityException e) {
//                e.printStackTrace();
//            }
//            // 文件名字
//            String fileName = new File(source).getName();
//            PdfSaveOptions options = new PdfSaveOptions();
//            // 输出路径
//            File pdfFile = new File(target + File.separator + (fileName.replace(fileExt, "pdf")));
//            OutputStream fileOS = new FileOutputStream(pdfFile);
//            wb.save(fileOS, options);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    /**
     * DOC -> DOCX
     *
     * @param inPath doc
     */

    public static String docToDocx(String inPath) {
        try {
            if (inPath.contains(PmConstants.DOC) && !inPath.contains(PmConstants.DOCX)) {
                String temp = inPath.replace(PmConstants.DOC, PmConstants.DOCX);
                File file = new File(temp);
                if (!file.exists()) {
                    SaveOutputParameters save = AsposeWordUtil.getInstance().getDocument(inPath).save(Files.newOutputStream(new File(temp).toPath()), SaveFormat.DOCX);
                    System.out.println("【doc转docx完成】");
                }
                return temp;
            }
        } catch (Exception e) {
            System.err.println("【doc转docx异常】" + e);
        }
        return inPath;
    }


//    @SneakyThrows
//    public static void ppt2Pdf() {
//        FileInputStream fileInput = new FileInputStream("C:\\Users\\zyc18\\Desktop\\123.ppt");
//        Presentation pres = new Presentation(fileInput);
//        FileOutputStream out = new FileOutputStream(new File("C:\\Users\\zyc18\\Desktop\\123.pdf"));
//        pres.save(out, SaveFormat.PDF);
//        out.close();
//    }

    /**
     * ppt转pdf
     *
     * @param pptPath ppt原文件地址
     * @param pdfDir  pdf输出目录
     * @return
     */
    public static boolean pptToPdf(String pptPath, String pdfDir) {
        if (StrUtil.isEmpty(pptPath)) {
            throw new RuntimeException("word文档路径不能为空");
        }
        if (StrUtil.isEmpty(pdfDir)) {
            throw new RuntimeException("pdf目录不能为空");
        }
        String pdfPath = StrUtil.replace(pptPath, StrUtil.subSuf(pptPath, pptPath.lastIndexOf(StrUtil.DOT)), ".pdf");
        com.itextpdf.text.Document document = null;
        HSLFSlideShow hslfSlideShow = null;
        FileOutputStream fileOutputStream = null;
        PdfWriter pdfWriter = null;
        try {
            hslfSlideShow = new HSLFSlideShow(new FileInputStream(pptPath));
            // 获取ppt文件页面
            Dimension dimension = hslfSlideShow.getPageSize();
            fileOutputStream = new FileOutputStream(pdfPath);
            document = new com.itextpdf.text.Document();
            // pdfWriter实例
            pdfWriter = PdfWriter.getInstance(document, fileOutputStream);
            document.open();
            PdfPTable pdfPTable = new PdfPTable(1);
            List<HSLFSlide> hslfSlideList = hslfSlideShow.getSlides();
            for (int i = 0; i < hslfSlideList.size(); i++) {
                HSLFSlide hslfSlide = hslfSlideList.get(i);
                // 设置字体, 解决中文乱码
                for (HSLFShape shape : hslfSlide.getShapes()) {
                    if (shape instanceof HSLFTextShape) {
                        HSLFTextShape textShape = (HSLFTextShape) shape;
                        for (HSLFTextParagraph textParagraph : textShape.getTextParagraphs()) {
                            for (HSLFTextRun textRun : textParagraph.getTextRuns()) {
                                textRun.setFontFamily("宋体");
                            }
                        }
                    }
                }
                BufferedImage bufferedImage = new BufferedImage((int) dimension.getWidth(), (int) dimension.getHeight(), BufferedImage.TYPE_INT_RGB);
                Graphics2D graphics2d = bufferedImage.createGraphics();
//                graphics2d.setPaint( Color.getWhite());
                graphics2d.setFont(new Font("宋体", Font.PLAIN, 12));
                hslfSlide.draw(graphics2d);
                graphics2d.dispose();
                com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance(bufferedImage, null);
                image.scalePercent(50f);
                // 写入单元格
                pdfPTable.addCell(new PdfPCell(image, true));
                document.add(image);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (document != null) {
                    document.close();
                }
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
                if (pdfWriter != null) {
                    pdfWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    /**
     * pptx转pdf
     *
     * @param pptPath 原ppt文件路径
     * @param pdfDir  pdf输出目录
     * @return
     */
    public static boolean pptxToPdf(String pptPath, String pdfDir) {
        log.info("pptPath" + ":" + pptPath);
        log.info("pdfDir" + ":" + pdfDir);
        if (StrUtil.isEmpty(pptPath)) {
            throw new RuntimeException("word文档路径不能为空");
        }
        if (StrUtil.isEmpty(pdfDir)) {
            throw new RuntimeException("pdf目录不能为空");
        }
        String pdfPath = StrUtil.replace(pptPath, StrUtil.subSuf(pptPath, pptPath.lastIndexOf(StrUtil.DOT)), ".pdf");
        com.itextpdf.text.Document document = null;
        XMLSlideShow slideShow = null;
        FileOutputStream fileOutputStream = null;
        PdfWriter pdfWriter = null;
        try {
            slideShow = new XMLSlideShow(new FileInputStream(pptPath));
            Dimension dimension = slideShow.getPageSize();
            fileOutputStream = new FileOutputStream(pdfPath);
            document = new com.itextpdf.text.Document();
            pdfWriter = PdfWriter.getInstance(document, fileOutputStream);
            document.open();
            PdfPTable pdfPTable = new PdfPTable(1);
            List<XSLFSlide> slideList = slideShow.getSlides();
            for (int i = 0, row = slideList.size(); i < row; i++) {
                XSLFSlide slide = slideList.get(i);
                // 设置字体, 解决中文乱码
                for (XSLFShape shape : slide.getShapes()) {
                    if (shape instanceof XSLFTextShape) {
                        XSLFTextShape textShape = (XSLFTextShape) shape;
                        for (XSLFTextParagraph textParagraph : textShape.getTextParagraphs()) {
                            for (XSLFTextRun textRun : textParagraph.getTextRuns()) {
                                textRun.setFontFamily("宋体");
                            }
                        }
                    }
                }
                BufferedImage bufferedImage = new BufferedImage((int) dimension.getWidth(), (int) dimension.getHeight(), BufferedImage.TYPE_INT_RGB);
                Graphics2D graphics2d = bufferedImage.createGraphics();
//                graphics2d.setPaint(Color.white);
                graphics2d.setFont(new Font("宋体", Font.PLAIN, 12));
                slide.draw(graphics2d);
                graphics2d.dispose();
                com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance(bufferedImage, null);
                image.scalePercent(50f);
                // 写入单元格
                pdfPTable.addCell(new PdfPCell(image, true));
                document.add(image);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (document != null) {
                    document.close();
                }
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
                if (pdfWriter != null) {
                    pdfWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    /**
     * txt转pdf
     *
     * @param txtPath txt文本路径
     * @param pdfPath pdf生成路径
     */
    public static void txtToPdf(String txtPath, String pdfPath) {
        try {
            com.itextpdf.text.Document document = new com.itextpdf.text.Document();
            PdfWriter.getInstance(document, new FileOutputStream(pdfPath));
            document.open();

            BufferedReader br = new BufferedReader(new FileReader(txtPath));
            String line;
            while ((line = br.readLine()) != null) {
                com.itextpdf.text.Paragraph paragraph = new com.itextpdf.text.Paragraph(line);
                document.add(paragraph);
            }

            br.close();
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("转换失败：" + e.getMessage());
        }
    }


    //    WebRequest req = WebRequest.Create(@"https://docs.oracle.com/javase/tutorial/networking/urls/readingURL.html");
    // Get web page into streamusing (Stream stream = req.GetResponse().GetResponseStream()){
    // Initialize HTML load optionsHtmlLoadOptions htmloptions = new HtmlLoadOptions("https://docs.oracle.com/");// Load stream into Document objectDocument pdfDocument = new Document(stream, htmloptions);// Save output as PDF formatpdfDocument.Save("HTML-to-PDF.pdf");}
    @SneakyThrows
    public static void main(String[] args) {
//        org.jsoup.nodes.Document jsoupDoc = Jsoup.connect("https://blog.csdn.net/weixin_30670053/article/details/114709086").userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31").timeout(10000).get();
//        System.out.println(jsoupDoc.html());
//        String html = jsoupDoc.html();
//        html = html.replaceAll("&nbsp;", "&#160;");
//        String fileName = "C:\\Users\\Administrator\\Desktop\\1\\index.html";
//        AsposeWordUtil.doc2pdf(fileName,"C:/2.pdf");
//        String fileName = "D:/modeldoc/model_wmy_report.doc";
//        docToDocx(fileName);
//        excel2pdf("C:\\Users\\zyc18\\Desktop\\资料\\1.xls", "C:\\Users\\zyc18\\Desktop\\资料\\", "xls");
//        ppt2pdf("C:\\Users\\zyc18\\Desktop\\资料\\cc.pptx", "C:\\Users\\zyc18\\Desktop\\资料\\", ".ppt");
//String string = "#空气质量分析#";
////        Pattern pattern = Pattern.compile("#(.+?)#");
////        Matcher matcher = pattern.matcher(string);
////        while (matcher.find()){
////            System.out.println(matcher.group());
////            continue;
////        }
//
//        System.out.println(string.split( "#" ));
//
//
//
//        int num1 = 0;
//        char[] sta = string.toCharArray();
//        for(int i = 0 ; i<string.length() ; i++) {
//            //英文字符g对应的是103（分大小写），下面有查看某个字符代表的具体数字的方法
//            //查看有几个‘g’出现在这个字符串

//            if(string.codePointAt(i) == '#') {
//                num1++;
//            }
//        }
//        Arrays.toString(sta).replaceAll("[\\[\\]\\s,]", "");
//        System.out.println(Arrays.toString(sta).replaceAll("[\\[\\]\\s,]", ""));
//        System.out.println(num1);
//        pptToPdf("C:\\Users\\zyc18\\Desktop\\123.ppt", "C:\\Users\\zyc18\\Desktop\\");
//        pptxToPdf("/home/zhhq/znqy/uploadPath/help/555.pptx", "/home/zhhq/znqy/uploadPath/help/");
        txtToPdf("C:\\Users\\zyc18\\Desktop\\新建 文本文档 (2).txt", "C:\\Users\\zyc18\\Desktop\\新建 文本文档 (2).pdf");
    }

}

